package com.devo.icecream.modbus

import android.os.Handler
import com.devo.icecream.AppLogger
import com.serotonin.modbus4j.BatchRead
import com.serotonin.modbus4j.ModbusMaster
import com.serotonin.modbus4j.code.DataType
import com.serotonin.modbus4j.locator.BaseLocator
import com.serotonin.modbus4j.msg.WriteRegisterRequest

class PLCStatus(private val master: ModbusMaster, private val workHandler: Handler) {
    //温度
    var temperature = 0f

    //PLC运行状态
    var runStatus = 0f

    //库存的总报警
    var isTotalStockWarn = false//设备存库预警状态 0无信息 1正常 2故障

    //plc运行错误标识
    var isPLCError = false

    //温度
    private val temperatureRequest =
        BaseLocator.holdingRegister(1, 9000, DataType.FOUR_BYTE_FLOAT_SWAPPED)

    //PLC运行状态
    private val runStatusRequest =
        BaseLocator.holdingRegister(1, 9002, DataType.FOUR_BYTE_FLOAT_SWAPPED)

    //库存的总报警
    private val warnStatusRequest = BaseLocator.inputStatus(1, 5000)

    //总故障标志
    private val errorStatusRequest = BaseLocator.inputStatus(1, 2000)


    // TODO: 2022/3/24 通过心跳确定连接状态，但目前心跳连接逻辑不清楚
    val isConnectStatus = false

    private fun loopQuery() {
        workHandler.postDelayed({
            //循环查询
            query()
            loopQuery()
        }, 1000)
    }

    private fun query() {
        val batchRead = BatchRead<String>()
        val time = System.currentTimeMillis().toString()
        var offset = 0
        //查询温度 库存等
        batchRead.addLocator("${time}-${++offset}", temperatureRequest)
        batchRead.addLocator("${time}-${++offset}", runStatusRequest)
        batchRead.addLocator("${time}-${++offset}", warnStatusRequest)
        batchRead.addLocator("${time}-${++offset}", errorStatusRequest)
        try {
            synchronized(this) {
                offset = 0
                master.trySend(batchRead)?.let { batchResults ->
                    temperature = batchResults.getFloatValue("${time}-${++offset}")
                    runStatus = batchResults.getFloatValue("${time}-${++offset}")
                    //库存的总报警
                    isTotalStockWarn = batchResults.getValue("${time}-${++offset}") as Boolean
                    //总故障标志
                    isPLCError = batchResults.getValue("${time}-${++offset}") as Boolean
                }
            }
        } catch (e: Exception) {
            AppLogger.e(e, "queryStatus")
            isPLCError = true
        }
    }

    //获取PLC运行状态
    fun checkStatus(): Boolean {
        return runStatus == 1f
    }

    //  营业状态 0:打烊 1:营业 向plc发送是否营业
    fun setMaintains(isMaintain: Boolean) {
        workHandler.post {
            master.trySend(
                WriteRegisterRequest(
                    1,
                    8002,
                    if (isMaintain) 1 else 0
                )
            )
        }
    }

    //plc总运行状态 温度等信息实体类
    fun toJson(): Map<String, Any> {
        return mapOf(
            "warnStatus" to "${if (isTotalStockWarn) 2 else 1}",//设备存库预警状态 0无信息 1正常 2故障
            "malfunctionStatus" to "${if (isPLCError) 2 else 1}",//设备故障状态 0无信息 1正常 2故障
            "temperature" to "$temperature"//设备温度
        )
    }

    init {
        loopQuery()
    }
}